﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;
namespace 面向对象
{
    /// <summary>
    /// 里氏转换：
    /// 1，子类可以赋值给父类
    /// 2. 如果父类中装的是子类，那么可以将这个父类强制转换成子类对象
    /// 
    /// 
    /// 多态：
    /// 1，父类引用指向子类对象
    /// 2，父类中有一个虚方法，子类重写了这个虚方法
    /// 3，调用父类的虚方法，实际上调用的是子类的方法
    /// 4，多态的实现是通过虚方法来实现的
    /// 5，多态的好处是可以让代码更灵活，更易于扩展
    /// 6，多态的缺点是性能开销大，因为需要在运行时进行方法的查找
    /// 
    /// 接口：
    /// 1，接口是一种特殊的类，它只包含方法的声明，没有方法的实现
    /// 2，接口可以被多个类实现，一个类可以实现多个接口
    /// 3，接口可以被继承，一个接口可以继承多个接口
    /// 4，接口可以被多态使用
    /// 
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Dog d = new Dog();
            d.Name = "haha";
            d.Age = 1;
            d.Height = 100;
            d.Show();
            d.eat();
            d.Run();
            //d.eat();

            // 第二种初始化的方法
            d = new Dog()
            {
                Name = "zhangsan",
                Age = 1,
                Height = 100,
            };
            d.Age = 23;
            d.Height = 45;
            d.Show();
            d.Eat("苹果");

            //Cat c = new Cat();
            //c.eat();

            //// 多态
            //Animal a = new Cat();
            //a.eat();

            // 分割线
            Console.WriteLine("分割线---------------------");
           
            Animal a = new Dog(); // 父类引用指向子类对象
            a.eat(); // 调用子类的eat方法

            a = new Cat(); // 父类引用指向子类对象
            a.eat(); // 调用子类的eat方法


            // 分割线
            Console.WriteLine("分割线---------------------");

            BaseClass bc = new BaseClass(); // 创建父类对象

            SubClass sc = new SubClass(); // 创建子类对象

            sc.func(); // 调用子类的虚方法

            sc.func2(); // 调用子类的非虚方法

            bc.func2(); // 调用父类的非虚方法

            sc.func3(); // 调用子类的非虚方法    

            // 分割线
            Console.WriteLine("分割线---------------------");

            BaseClass b = new SubClass(); // 父类引用指向子类对象
            b.func(); // 调用子类的虚方法
            b.func2(); // 调用父类的非虚方法
            b.func3(); // 调用父类的非虚方法


            Console.ReadKey();
        }
    }


    // 接口
    interface Animal
    {
        void eat();
    }

    /// <summary>
    /// Dog类
    /// </summary>
    public class Dog : Animal
    {
        public string FName; // 这个是字段，用来存放数据的

        // 这些是属性，属性访问器
        public string Name { 
            
            get { return FName; } // get 访问器
             
            set {FName = value;}  // set 访问器
        }

        public int Age { get; set; }
        public float Height { get; set; }

        public void eat()
        {
            Console.WriteLine("狗改不了吃屎");
        }

        public void Eat(string food)
        {
            Console.WriteLine("{0} 在吃 {1}",this.Name,food);
        }

        public void Run()
        {
            Console.WriteLine("狗跑的非常快");
        }

        public void Show()
        {
            Console.WriteLine("名字：{0},年龄：{1},身高：{2}",Name, Age, Height);
        }
    }

    /// <summary>
    /// Cat类
    /// </summary>
    public class Cat : Animal
    {
        public void eat()
        {
            Console.WriteLine("猫总是舔毛");
        }
    }



    /// <summary>
    /// 基类
    /// </summary>
    public class BaseClass
    {
        /// <summary>
        /// 虚方法
        /// </summary>
        public virtual void func()
        {
            Console.WriteLine("BaseClass virtual void func");
        }

        public void func2()
        {
            Console.WriteLine("BaseClass void func2");
        }

        public void func3()
        {
            Console.WriteLine("BaseClass void func3");
        }
    }

    /// <summary>
    /// 子类
    /// </summary>
    public class SubClass : BaseClass
    {
        /// <summary>
        /// 重写父类的虚方法
        /// </summary>
        public override void func()
        {
            Console.WriteLine("SubClass override void func");
        }

        new public void func2()
        {
            Console.WriteLine("SubClass void func2");
        }

        new public void func3()
        {
            base.func3();
            Console.WriteLine("SubClass void func3");
        }
    }

}
